﻿using System;
using System.Collections.Generic;
using System.Windows.Forms;
using RayTracerLib.Reader;
using System.IO;
namespace Editor
{
    public partial class MainForm : Form
    {
        PresentationForm _presenter;
        SceneManager CurrentManager { get; set; }
        private PluginManager PluginManager { get; set; }
        private string CurrentScene { get { return txt_scene.Text; } set { txt_scene.Text = value; } }
        public MainForm()
        {
            InitializeComponent();
            CurrentManager = new SceneManager();
            PluginManager = new PluginManager();
            PluginManager.LoadPlugins();
            PluginManager.Current = PluginManager;
        }

        #region Open
        private void OpenToolStripMenuItemClick(object sender, EventArgs e)
        {
            if (!CurrentManager.Equals(CurrentScene))
            {
                var result = MessageBox.Show(@"Сохранить изменения в файле?", "", MessageBoxButtons.YesNoCancel);
                if (result == DialogResult.Cancel) return;
                if (result == DialogResult.Yes)
                    CurrentManager.Save(CurrentScene);
                OpenScene();
            }
            else
                OpenScene();
        }
        private void OpenScene()
        {
            var dlg = new OpenFileDialog();
            if (dlg.ShowDialog() == DialogResult.OK)
            {
                CurrentManager = new SceneManager(dlg.FileName);
                CurrentScene = CurrentManager.Scene;
            }
        }
        private void OpenScene(string path)
        {
            CurrentManager = new SceneManager(path);
            CurrentScene = CurrentManager.Scene;
        }
        #endregion
        private void ExitToolStripMenuItemClick(object sender, EventArgs e)
        {
            Close();
        }

        private void ValidateToolStripMenuItemClick(object sender, EventArgs e)
        {
            lv_errors.Items.Clear();
            var validator = new Validator(txt_scene.Text);
            if (validator.Validate())
                statusLabel.Text = @"Сцена успешно распознана";
            else
            {
                statusLabel.Text = @"Обнаружены ошибки в описании сцены";
                FillErrorsListView(validator.Errors);
            }
        }

        private void FillErrorsListView(IEnumerable<Error> errors)
        {
            lv_errors.Items.Clear();
            foreach (Error err in errors)
            {
                var item =
                    new ListViewItem(new[]
                                         {
                                             err.Description,
                                             txt_scene.GetLineFromCharIndex(err.IndexCharPosition).ToString(),
                                             (err.IndexCharPosition -
                                              txt_scene.GetFirstCharIndexFromLine(
                                                  txt_scene.GetLineFromCharIndex(err.IndexCharPosition))).ToString()
                                         }) { Tag = err };
                lv_errors.Items.Add(item);
            }
        }
        private void RenderToolStripMenuItemClick(object sender, EventArgs e)
        {
            lv_errors.Items.Clear();
            var validator = new Validator(txt_scene.Text);
            if (validator.Validate())
            {
                if (_presenter == null)
                    _presenter = new PresentationForm(validator.Scene);
                else
                    _presenter.Scene = validator.Scene;
                _presenter.ShowDialog();
            }
            else
            {
                MessageBox.Show(@"Обнаружены ошибки в описании сцены");
                FillErrorsListView(validator.Errors);
            }
        }

        private void LvErrorsMouseDoubleClick(object sender, MouseEventArgs e)
        {
            if (lv_errors.SelectedItems.Count > 0)
            {
                var error = lv_errors.SelectedItems[0].Tag as Error;
                if (error != null)
                    txt_scene.SelectionStart = error.IndexCharPosition;
                txt_scene.Focus();
            }
        }
        private void CreateEmptyScene()
        {
            CurrentManager = new SceneManager();
            CurrentScene = string.Empty;
        }
        private void CreateToolStripMenuItemClick(object sender, EventArgs e)
        {
            if (!CurrentManager.Equals(CurrentScene))
            {
                DialogResult result = MessageBox.Show(@"Сохранить изменения в файле?", "", MessageBoxButtons.YesNoCancel);
                switch (result)
                {
                    case DialogResult.Yes:
                        CurrentManager.Save(CurrentScene);
                        break;
                    case DialogResult.No:
                        CreateEmptyScene();
                        break;
                }
            }
            else
                CreateEmptyScene();
        }

        private void SaveToolStripMenuItemClick(object sender, EventArgs e)
        {
            CurrentManager.Save(CurrentScene);
        }

        private void SaveasКакToolStripMenuItemClick(object sender, EventArgs e)
        {
            CurrentManager.SaveAs(CurrentScene);
        }
        #region Последние файлы
        private void FileToolStripMenuItemDropDownOpening(object sender, EventArgs e)
        {
            lastFilesToolStripMenuItem.DropDownItems.Clear();
            foreach (string str in Editor.Properties.Settings.Default.recentlyFiles)
            {
                var item = new ToolStripMenuItem(str);
                item.Click += RecentlyFileClick;
                lastFilesToolStripMenuItem.DropDownItems.Add(item);
            }
            lastFilesToolStripMenuItem.Enabled = lastFilesToolStripMenuItem.DropDownItems.Count > 0;
        }

        void RecentlyFileClick(object sender, EventArgs e)
        {            
            string file = ((ToolStripMenuItem) sender).Text;
            if (File.Exists(file))
            {
                if (!CurrentManager.Equals(CurrentScene))
                {
                    DialogResult result = MessageBox.Show(@"Сохранить изменения в файле?", "", MessageBoxButtons.YesNoCancel);
                    if (result == DialogResult.Cancel) return;
                    if (result == DialogResult.Yes)
                        CurrentManager.Save(CurrentScene);
                    OpenScene(file);
                }
                else
                    OpenScene(file);
            }
            else
            {
                MessageBox.Show(@"Файл " + file + @" не найден");
                Editor.Properties.Settings.Default.recentlyFiles.Remove(file);
            }
        }
        #endregion


        #region Материалы
        private void IncludeGoldToolStripButtonClick(object sender, EventArgs e)
        {
            var goldMaterial = @"def Gold{ ambient 0.24725 0.1995 0.0745"+'\r'+'\n'+
                    "diffuse 0.75164 0.60648 0.22648" + '\r' + '\n' +
                    "specular 0.628281 0.555802 0.366065" + '\r' + '\n' +
                    "reflectivity 0.4" + '\r' + '\n' +
                    "specularExponent 90}" + '\r' + '\n';
            txt_scene.Text = txt_scene.Text.Insert(txt_scene.SelectionStart, goldMaterial);
        }
        #endregion
    }
}
